/*
 * test_tree_with_file.cpp
 *
 *  Created on: Nov 4, 2012
 *      Author: Federico Orquera
 */

#include <string>
#include <iostream>
#include <fstream>
#include "BPlusTreeTemplate.h"
#include "bplusfilehandler/BPlusTreeFile.h"

using std::cout;
using std::endl;
using std::string;

#define MAX_CICLES 25

void invalid_args()
{
    std::cerr << "Argumentos inválidos."<< std::endl;
    std::cerr << "bpt_ts blockSize/64 maxCicles(fullindex if omited) ."<< std::endl;
    exit(1);
}

void PRINT_STATUSBAR(unsigned int currentValue, unsigned int total) {
	if(currentValue == 1)				 {cout<<"| 0% ---"; fflush(stdout);}
	if(currentValue == (int)(total/10))	 {cout<<" 10% ---"; fflush(stdout);}
	if(currentValue == (int)(2*total/10)){cout<<" 20% ---"; fflush(stdout);}
	if(currentValue == (int)(3*total/10)){cout<<" 30% ---"; fflush(stdout);}
	if(currentValue == (int)(4*total/10)){cout<<" 40% ---"; fflush(stdout);}
	if(currentValue == (int)(5*total/10)){cout<<" 50% ---"; fflush(stdout);}
	if(currentValue == (int)(6*total/10)){cout<<" 60% ---"; fflush(stdout);}
	if(currentValue == (int)(7*total/10)){cout<<" 70% ---"; fflush(stdout);}
	if(currentValue == (int)(8*total/10)){cout<<" 80% ---"; fflush(stdout);}
	if(currentValue == (int)(9*total/10)){cout<<" 90% ---"; fflush(stdout);}
	if(currentValue == (int)(total-1))	 {cout<<" 100% --- | Done!\n"; fflush(stdout);}
}

int main(int argc, char *argv[])
{
    size_t blockSize, maxCycles = 0;
    bool fullIndex = true;

    if ( argc < 2 || argc > 3 )
        invalid_args();

    blockSize = atoi( argv[1] );
    blockSize *= 64;

    if ( blockSize <= 0 )
        invalid_args();

    if ( argc == 3 )
    {
       maxCycles = atoi( argv[2] );

       if( maxCycles <= 0 )
           invalid_args();

       fullIndex = false;
    }


	string inputFile = "../sorted.txt";
    //string inputFile = "../wordlist.normalized.txt";
	string key;

	DTRkey_t	test1 ("a");
	LeafRegister_ptr testPtr1 (new LeafRegister_t(test1, {}));

	BPlusTreeFile mock(string("fulltest.bpt"),blockSize,true);

	BPlusTreeTemplate<DTRkey_t, DTRvalue_t, keyComparator_func> testTree(&mock);

	ifstream myfile (inputFile);

	if (!myfile.is_open()){
		cout<<"No se pudo abrir "<<inputFile<<endl;
		return 0;
	}

	ofstream listIn ("list.in");

	if (!listIn.is_open()){
		cout<<"No se pudo abrir list.in"<<endl;
		return 0;
	}

	ofstream listOut ("list.out");

	if (!listOut.is_open()){
		cout<<"No se pudo abrir list.out"<<endl;
		return 0;
	}

	LeafRegister_ptr temp_ptr;

	unsigned int count = 0;

	while (
			( fullIndex || count < maxCycles ) &&
			getline (myfile,key) )
	{
		if (true || key.find("ñ",0)==string::npos){

			listIn<<key<<endl;
			temp_ptr.reset(new LeafRegister_t(key,  {15,20}));

			//testTree.LoadRegister( temp_ptr );
			//cout<<endl<<"Ciclo:"<<count<<" Inserto: "<<key<<endl;//<<" en :"<<endl;

			if(fullIndex == false)PRINT_STATUSBAR(count, maxCycles);

			testTree.InsertRegister( temp_ptr );
			//testTree.MostrarContenidoReducido();
			count++;
		}
	}
	//testTree.MostrarContenidoReducido();
	myfile.close();
	listIn.close();

	cout<<"Generando lista ordenada... "<<endl<<endl;

	searchResult_t resultado = testTree.SearchRegister(testPtr1->getKey());
	//cout<<"Buscando: "<<testPtr1->getKey()<<endl;
	//cout<<"resultado:{ nextNode: "<<resultado.nextNode<<" key: "<<resultado.result->getKey()<<" valid: "<<((resultado.valid)?"TRUE ":"FALSE ")<<resultado.result->getKey()<<" end Of List: "<<((resultado.endOfList)?"TRUE":"FALSE")<<" }"<<endl<<endl;

	testTree.SearchNextRegister(resultado);

	while(!resultado.endOfList){
		listOut<<resultado.result->getKey()<<endl;
		//cout<<"Buscando: "<<resultado.result->getKey()<<endl;
		resultado = testTree.SearchNextRegister(resultado);
		//cout<<"resultado:{ nextNode: "<<resultado.nextNode<<" key: "<<resultado.result->getKey()<<" valid: "<<((resultado.valid)?"TRUE ":"FALSE ")<<resultado.result->getKey()<<" end Of List: "<<((resultado.endOfList)?"TRUE":"FALSE")<<" }"<<endl<<endl;

	}

	listOut<<resultado.result->getKey()<<endl;
	listOut.close();


	//Obtendo un registro valido
	/*resultado = testTree.SearchRegister(testPtr1->getKey());

	cout<<"resultado:{ nextNode: "<<resultado.nextNode<<" key: "<<resultado.result->getKey()<<" valid: "<<((resultado.valid)?"TRUE ":"FALSE ")<<resultado.result->getKey()
		<<" end Of List: "<<((resultado.endOfList)?"TRUE":"FALSE")
		<<" value :{ relativePosition: "<<(resultado.result->getValue()).relativePosition
				 <<" reserved: "<<(resultado.result->getValue()).reserved<<" } "<<" }"<<endl<<endl;

	DTRvalue_t newValue;

	newValue.relativePosition = 64;
	newValue.reserved = 1;

	resultado.result->setValue(newValue);

	testTree.UpdateRegister(resultado.result);

	resultado = testTree.SearchRegister(resultado.result->getKey());

	cout<<"resultado:{ nextNode: "<<resultado.nextNode<<" key: "<<resultado.result->getKey()<<" valid: "<<((resultado.valid)?"TRUE ":"FALSE ")<<resultado.result->getKey()
		<<" end Of List: "<<((resultado.endOfList)?"TRUE":"FALSE")
		<<" value :{ relativePosition: "<<(resultado.result->getValue()).relativePosition
				 <<" reserved: "<<(resultado.result->getValue()).reserved<<" } "<<" }"<<endl<<endl;


	LeafRegister_ptr testPtr2 (new LeafRegister_t("Esta key no existe!", {}));
	testTree.UpdateRegister(testPtr2);*/

	cout<<"Listo!"<<endl;

	return 0;
}
